package router

import (
	"bytes"
	"sync"

	"gitee.com/shibingli/fastweb/commons"
	"gitee.com/shibingli/fastweb/log"
	"github.com/valyala/fasthttp"
)

type RequestCtx struct {
	noCopy commons.NoCopy

	Logger *log.Logger
	Env    *commons.Environment
	*fasthttp.RequestCtx
}

var requestCtxPool = sync.Pool{
	New: func() interface{} {
		return new(RequestCtx)
	},
}

func UpgradeCTX(fCtx *fasthttp.RequestCtx) *RequestCtx {
	ctx := requestCtxPool.Get().(*RequestCtx)
	if ctx == nil {
		ctx = &RequestCtx{}
	}
	ctx.RequestCtx = fCtx
	ctx.Logger = commons.Logger
	ctx.Env = commons.Env
	return ctx
}

func ReleaseCTX(ctx *RequestCtx) {
	requestCtxPool.Put(ctx)
}

func (ctx *RequestCtx) Reset() {
	ctx.RequestCtx = nil
	ctx.Logger = nil
	ctx.Env = nil
}

func (ctx *RequestCtx) RequestID() []byte {
	return ctx.Request.Header.Peek(commons.HeaderRequestIDKey)
}

func (ctx *RequestCtx) WriteString(data string) (int, error) {
	defer ReleaseCTX(ctx)
	return ctx.RequestCtx.WriteString(data)
}

func (ctx *RequestCtx) Write(data []byte) (int, error) {
	defer ReleaseCTX(ctx)
	return ctx.RequestCtx.Write(data)
}

func (ctx *RequestCtx) WriteViewBuffer(buffer *bytes.Buffer) (int, error) {
	defer ReleaseCTX(ctx)
	ctx.SetContentType(commons.HTMLContentType)
	return ctx.RequestCtx.Write(buffer.Bytes())
}

func (ctx *RequestCtx) WriteViewBytes(data []byte) (int, error) {
	defer ReleaseCTX(ctx)
	ctx.SetContentType(commons.HTMLContentType)
	return ctx.RequestCtx.Write(data)
}

func (ctx *RequestCtx) WriteJsonBytes(data []byte) (int, error) {
	defer ReleaseCTX(ctx)
	ctx.SetContentType(commons.JSONContentType)
	return ctx.RequestCtx.Write(data)
}
